package com.example.sangong.utils;

import cn.hutool.core.util.RandomUtil;
import com.example.sangong.entity.CardGroup;
import com.example.sangong.entity.Player;
import com.example.sangong.entity.Room;
import com.example.sangong.entity.UserPlayRecord;
import com.example.sangong.myenum.ScoreEnum;
import com.example.sangong.req.CalCreditParamReq;
import com.example.sangong.req.RoomInfoReq;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class RoomUtils {

    private static Map<String, Room> cache = new HashMap<>();

    /**
     * 获取房间的牌组
     *
     * @param roomNo
     * @return
     */

    public static CardGroup getCardGroup(String roomNo) {
        Room room = cache.get(roomNo);
        if (room == null) {
            throw new RuntimeException("房间不存在");
        }
        return room.getCardGroup();
    }

    public static Room initRoom(String roomName, List<Player> playerList) {
        Room room = new Room();
        room.setRoomName(roomName);
        room.setRoomNo(RandomUtil.randomNumbers(10));
//        room.setRoomNo("99999");
        room.setCardGroup(CardGroupUtils.build());
        room.setPlayerList(playerList);
        return room;
    }

    public static void start(Room room, int cutCardNum) {
        CardGroupUtils.sendCard(room.getPlayerList(), cutCardNum, room.getCardGroup());
        List<Player> playerList = room.getPlayerList();
        Player master = playerList.get(0);
        master.setIsHead(true);
        Player masterPlayer = null;
        List<Player> followerPlayerList = new ArrayList<>();
        //计算点数
        for (Player player : playerList) {

            ScoreEnum scoreEnum = RuleUtils.calScore(player.getCardList());

            player.setScoreEnum(scoreEnum);
            if (player.getIsHead()) {
                masterPlayer = player;
            } else {
                followerPlayerList.add(player);
            }
            log.info("玩家:{}:牌为:{},成绩为:{}", player.getUser().getName(), player.getCardList(), scoreEnum);


        }
        cache.put(room.getRoomNo(), room);
        //计算积分
        ScoreUtils.storeScore(masterPlayer, followerPlayerList);
        //回收牌
        CardGroupUtils.recycleCard(room.getCardGroup());

        //庄家的积分为空0，游戏结束
        if (masterPlayer.getScore() == 0) {
            throw new RuntimeException("庄家输完了，游戏结束");
        }


    }

    public static Room initRoomInfo(RoomInfoReq roomInfoReq, int cutCardNum) {
        String roomNo = roomInfoReq.getRoomNo();
        String userId = roomInfoReq.getUserId();
        Room room;


        if (roomNo != null) {
            room = cache.get(roomNo);
        } else {
            room = RoomUtils.initRoom("天上人间", PlayerUtils.defaultPlayer());

        }


        clearPlayerCard(room.getPlayerList());
        checkHeadScoreIsZero(room.getPlayerList());
        room.setRoundNo(System.currentTimeMillis() + "");
        CardGroupUtils.sendCard(room.getPlayerList(), cutCardNum, room.getCardGroup());
        room.setAlreadyCalCredit(false);
        List<Player> playerList = room.getPlayerList();

        Player master = playerList.get(0);
        master.setIsHead(true);
        Player masterPlayer = null;
        List<Player> followerPlayerList = new ArrayList<>();
        List<UserPlayRecord> userPlayRecords = new ArrayList<>();
        //计算点数
        for (Player player : playerList) {

            ScoreEnum scoreEnum = RuleUtils.calScore(player.getCardList());

            player.setScoreEnum(scoreEnum);
            if (player.getIsHead()) {
                masterPlayer = player;
            } else {
                followerPlayerList.add(player);
            }
            UserPlayRecord userPlayRecord = getUserPlayRecord(room, player, scoreEnum);
            userPlayRecords.add(userPlayRecord);
            log.info("玩家:{}:牌为:{},成绩为:{}", player.getUser().getName(), player.getCardList(), scoreEnum);
        }
        UserPlayRecordDbUtils.add(room.getRoomNo(), userPlayRecords);
        CardGroup cardGroup = room.getCardGroup();
        initPlayerInfo(playerList, room, roomInfoReq.getUserId());
        log.info("发出去的牌有{}张，剩{}张,丢掉了{}张", cardGroup.getThrowList().size(), cardGroup.getNoUsedList().size(), cardGroup.getThrowList().size());
        cache.put(room.getRoomNo(), room);
        return room;

    }

    private static void initPlayerInfo(List<Player> playerList, Room room, String userId) {
        for (Player player : playerList) {
            if (player.getIsHead()) {
                room.setPlayerMaster(player);
                continue;
            }
            if (userId.equals(player.getUser().getId())) {
                room.setPlayerMe(player);
                continue;
            }
            if (room.getPlayerOne() == null) {
                room.setPlayerOne(player);
            } else {
                room.setPlayerTwo(player);
            }
        }

    }

    private static UserPlayRecord getUserPlayRecord(Room room, Player player, ScoreEnum scoreEnum) {
        UserPlayRecord userPlayRecord = new UserPlayRecord();
        userPlayRecord.setUserId(player.getUser().getId());
        userPlayRecord.setUserName(player.getUser().getName());
        userPlayRecord.setCardList(player.getCardList());
        userPlayRecord.setScore(scoreEnum);
        userPlayRecord.setCurrentCredit(player.getScore());
        userPlayRecord.setChip(player.getChip());
        userPlayRecord.setIsHead(player.getIsHead());
        userPlayRecord.setRoomNo(room.getRoomNo());
        userPlayRecord.setRoundNo(room.getRoundNo());
        return userPlayRecord;
    }


    public static void checkHeadScoreIsZero(List<Player> playerList) {
        for (Player player : playerList) {
            if (!player.getIsHead()) {
                continue;
            }
            if (player.getScore() <= 0) {
                throw new RuntimeException("庄家输完了，游戏结束");
            }
        }
    }

    public static List<Player> calCredit(CalCreditParamReq req) {
        String roomNo = req.getRoomNo();
        Room room = cache.get(roomNo);
        if (room == null) {
            throw new RuntimeException("房间已经不存在了");
        }
        if (room.isAlreadyCalCredit()) {
            throw new RuntimeException("已经计算完积分了，请开始下一轮游戏");
        }

        List<Player> playerList = room.getPlayerList();
        Player masterPlayer = null;
        List<Player> followerPlayerList = new ArrayList<>();
        //计算点数
        for (Player player : playerList) {

            ScoreEnum scoreEnum = RuleUtils.calScore(player.getCardList());

            player.setScoreEnum(scoreEnum);
            if (player.getIsHead()) {
                masterPlayer = player;
            } else {
                followerPlayerList.add(player);
            }
            log.info("玩家:{}:牌为:{},成绩为:{}", player.getUser().getName(), player.getCardList(), scoreEnum);


        }
        clearPlayerCard(playerList);
        //计算积分
        ScoreUtils.storeScore(masterPlayer, followerPlayerList);
        //添加记录
        UserPlayRecordDbUtils.update(req, playerList);
        //回收牌
        CardGroupUtils.recycleCard(room.getCardGroup());
        room.setAlreadyCalCredit(true);

        cache.put(room.getRoomNo(), room);
        return playerList;


    }

    private static void clearPlayerCard(List<Player> playerList) {
        //清空玩家的牌
        for (Player player : playerList) {
            player.setCardList(null);
        }
    }


    public static void run(Room room, int cutCardNum) {
        while (true) {
            start(room, cutCardNum);
        }
    }
}
